/**
 * JSparrow - Une version numérique du jeu "Attention Pirates !" - Copyright (C) 2014 Black Pearl
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program. If
 * not, see <http://www.gnu.org/licenses/>.
 */
package App.Modele;

import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 * Classe de test de la classe Plateau.
 *
 * @author BlackPearl
 */
public class PlateauTest {

    private Bateau b1;
    private Bateau b2;
    private ArrayList<Bateau> listeBateaux;
    private Plateau plateau;

    /**
     * Mettre en place le contexte des tests.
     */
    @Before
    public void setUp() {
        this.listeBateaux = new ArrayList<Bateau>();
        this.b1 = new Bateau(1);
        this.b2 = new Bateau(2);
        this.listeBateaux.add(this.b1);
        this.listeBateaux.add(this.b2);
        this.plateau = new Plateau(this.listeBateaux);
    }

    /**
     * Test de la méthode deplacerBateau de la classe Plateau.
     */
    @Test
    public void testDeplacerBateau() {
        assertEquals(false, this.plateau.deplacerBateau(this.b1, new Point(8, 8)));
        assertEquals(true, this.plateau.deplacerBateau(this.b1, new Point(1, 1)));
    }

    /**
     * Test de la méthode getDeplacementPossible de la classe Plateau.
     */
    @Test
    public void testGetDeplacementPossible() {
        ArrayList<Point> deplacements = new ArrayList<Point>();
        ArrayList<Point> resultats;
        deplacements.add(new Point(0, 4));
        deplacements.add(new Point(0, 2));
        deplacements.add(new Point(1, 1));
        deplacements.add(new Point(1, 3));
        deplacements.add(new Point(2, 2));
        Collections.sort(deplacements, new PointComparator());
        resultats = this.plateau.getDeplacementPossible(this.b1);
        Collections.sort(resultats, new PointComparator());
        assertEquals(deplacements, resultats);
    }

    /**
     * Test de la méthode isPieceAttaquable de la classe Plateau.
     */
    @Test
    public void testIsPieceAttaquable() {
        /**
         * @todo Implémenter le test quand méthode terminée.
         */
    }

    /**
     * Test de la méthode getPiecesAttaquables de la classe Plateau.
     */
    @Test
    public void testGetPiecesAttaquables() {
        /**
         * @todo Implémenter le test quand méthode terminée.
         */
    }

    /**
     * Test de la méthode checkAttaque de la classe Plateau.
     */
    @Test
    public void testCheckAttaque() {
        assertEquals(false, this.plateau.checkAttaque(this.b1, this.b2));
        this.plateau.deplacerBateau(this.b1, new Point(6, 6));
        assertEquals(false, this.plateau.checkAttaque(this.b1, this.b2));
        this.plateau.deplacerBateau(this.b1, new Point(2, 2));
        this.plateau.deplacerBateau(this.b2, new Point(2, 2));
        this.b1.setNbCanons(1);
        this.b1.setNbPirates(1);
        assertEquals(true, this.plateau.checkAttaque(this.b1, this.b2));
    }

    /**
     * Test de la méthode attaquer de la classe Plateau.
     */
    @Test
    public void testAttaquer() {
        assertEquals(false, this.plateau.checkAttaque(this.b1, this.b2));
        this.plateau.deplacerBateau(this.b1, new Point(6, 6));
        assertEquals(false, this.plateau.checkAttaque(this.b1, this.b2));
        this.plateau.deplacerBateau(this.b1, new Point(2, 2));
        this.plateau.deplacerBateau(this.b2, new Point(2, 2));
        this.b1.setNbCanons(1);
        this.b1.setNbPirates(1);
        int nbCanons = -1;
        int nbPirates = -1;
        int nbTresors = -1;
        ArrayList<Bateau> listBateaux = this.plateau.getListeBateaux();
        for (Bateau b : listBateaux) {
            if (b.getIdJoueur() == 2) {
                nbCanons = b.getNbCanons();
                nbPirates = b.getNbPirates();
                nbTresors = b.getNbTresors();
            }
        }
        boolean changes = false;
        assertEquals(true, this.plateau.checkAttaque(this.b1, this.b2));
        ArrayList<Bateau> listBateauxAfter = this.plateau.getListeBateaux();
        for (Bateau b : listBateauxAfter) {
            if (b.getIdJoueur() == 2) {
                if (nbCanons != b.getNbCanons()) {
                    changes = true;
                    break;
                }
                if (nbPirates != b.getNbPirates()) {
                    changes = true;
                    break;
                }
                if (nbTresors != b.getNbTresors()) {
                    changes = true;
                    break;
                }
            }
        }
        /**
         * @todo Terminer quand méthode terminée.
         */
        //assertEquals(true, changes);
    }

    /**
     * Test de la méthode checkDeplacement de la classe Plateau.
     */
    @Test
    public void testCheckDeplacement() {
        assertEquals(true, this.plateau.checkDeplacement(new Point(1, 1), this.b1));
        assertEquals(false, this.plateau.checkDeplacement(new Point(6, 6), this.b1));
    }

    /**
     * Test de la méthode getNbCreditReparation de la classe Plateau.
     */
    @Test
    public void testGetNbCreditReparation() {
        assertEquals(6, this.plateau.getNbCreditReparation(this.b1));
        this.b1.deplacer(new Point(6, 6));
        assertEquals(2, this.plateau.getNbCreditReparation(this.b1));
    }

    /**
     * Test de la méthode getRepaire de la classe Plateau.
     */
    @Test
    public void testGetRepaire() {
        assertNull(this.plateau.getRepaire(new Point(0, 0)));
        assertNull(this.plateau.getRepaire(new Point(6, 6)));
        Repaire repaire = this.plateau.getRepaire(new Point(6, 0));
        assertThat(repaire, instanceOf(EntiteCase.class));
    }
}
